package com.zqxq.lottery.api.controller;

import com.alibaba.fastjson.JSONObject;
import com.zqxq.common.constant.Result;
import com.zqxq.common.enums.CodeEnum;
import com.zqxq.common.utils.*;
import com.zqxq.lottery.api.feign.LotteryServerFeignClient;
import com.zqxq.lottery.api.service.IAlipayService;
import com.zqxq.lottery.api.service.IWechatService;
import com.zqxq.lottery.api.utils.MobileUtil;
import com.zqxq.lottery.api.utils.UserCenterHttps;
import com.zqxq.lottery.entity.bo.PasswordBO;
import com.zqxq.lottery.entity.bo.UserBO;
import com.zqxq.lottery.entity.po.user.UserWechatPO;
import com.zqxq.lottery.entity.vo.user.UserAlipayVO;
import com.zqxq.lottery.entity.vo.user.UserInfoVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description ：
 * @Author ： 解风
 * @Date ： 2018/01/04 16:59
 */
@Api(value = "用户接口",tags = "用户接口")
@RestController
@Slf4j
@RequestMapping(value="/user",produces = "application/json")
public class UserController {

    @Autowired
    private UserCenterHttps userCenterHttps;
    @Autowired
    private LotteryServerFeignClient lotteryServerFeignClient;
    @Autowired
    private IAlipayService alipayService;
    @Autowired
    private IWechatService wechatService;

    /**
     * 用户注册
     * @param userBO
     * @return
     */
    @PostMapping("/register")
    @ApiOperation(value = "用户注册", notes = "用户注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "登录密码", required = false, dataType = "String", defaultValue = "''"),
            @ApiImplicitParam(name = "verifyCode", value = "验证码", required = true, dataType = "String", defaultValue = "''")
    })
    public Result register(HttpServletRequest request, UserBO userBO) {
        log.info("手机用户【" + userBO.getMobile() + "】用户注册" + ",用户所在" + userBO.getAppKey() + "平台");
        String regIp = WebUtils.getClientIP(request);
        try {
            String mobile = userBO.getMobile();
            String password = userBO.getPassword();
            if(StrUtils.isNotEmpty(password)){
                userBO.setPassword(Md5Utils.encryption("a123456"));
            }
            String verifyCode = userBO.getVerifyCode();
            if (StrUtils.isEmpty(mobile) || !MobileUtil.isMobile(mobile) || StrUtils.isEmpty(verifyCode)) {
                return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
            }
            Map<String, Object> resultMap = userCenterHttps.regUser(userBO);
            int code = CodeEnum.FAIL.getCode();
            String msg = CodeEnum.FAIL.getMsg();
            Map<String, Object> map = new HashMap<String, Object>();
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                msg = resultMap.get("msg") == null ? CodeEnum.FAIL.getMsg() : resultMap.get("msg").toString();
                if(backCode == 1){
                    code = 0;
                    msg = CodeEnum.SUCCESS.getMsg();
                    Map<String, Object> data = (Map<String, Object>) resultMap.get("data");
                    map.put("userId", data.get("user_id"));
                }
            }
            return new Result(code, msg, map);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("登录失败！", e);
            return new Result(CodeEnum.FAIL_100005.getCode(), CodeEnum.FAIL_100005.getMsg());
        }
    }

    /**
     * 根据旧密码修改密码
     * @param passwordBO
     * @return
     */
    @PostMapping("/updatePassword")
    @ApiOperation(value = "根据旧密码修改密码", notes = "根据旧密码修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "登录密码", required = false, dataType = "String", defaultValue = "''"),
            @ApiImplicitParam(name = "oldPassword", value = "旧密码", required = true, dataType = "String", defaultValue = "''")
    })
    public Result updatePassword(HttpServletRequest request, PasswordBO passwordBO) {
        log.info("手机用户【" + passwordBO.getMobile() + "】正在登录" + ",用户所在" + passwordBO.getAppKey() + "平台");
        String regIp = WebUtils.getClientIP(request);
        try {
            String mobile = passwordBO.getMobile();
            String password = passwordBO.getPassword();
            String oldPassword = passwordBO.getOldPassword();
            if (StrUtils.isEmpty(mobile) || !MobileUtil.isMobile(mobile) || StrUtils.isEmpty(oldPassword) || StrUtils.isEmpty(password)) {
                return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
            }
            Map<String, Object> resultMap = userCenterHttps.updatePassword(passwordBO);
            int code = CodeEnum.FAIL.getCode();
            String msg = CodeEnum.FAIL.getMsg();
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                msg = resultMap.get("msg") == null ? CodeEnum.FAIL.getMsg() : resultMap.get("msg").toString();
                if(backCode == 1){
                    code = 0;
                    msg = CodeEnum.SUCCESS.getMsg();
                }
            }
            return new Result(code, msg);
        } catch (Exception e) {
            log.error("根据旧密码修改密码失败！", e);
            return new Result(CodeEnum.FAIL_100005.getCode(), CodeEnum.FAIL_100005.getMsg());
        }
    }

    /**
     * 根据验证码修改密码
     * @param passwordBO
     * @return
     */
    @PostMapping("/updatePasswordVerifyCode")
    @ApiOperation(value = "根据验证码修改密码", notes = "根据验证码修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "登录密码", required = false, dataType = "String", defaultValue = "''"),
            @ApiImplicitParam(name = "verifyCode", value = "验证码", required = true, dataType = "String", defaultValue = "''")
    })
    public Result updatePasswordVerifyCode(HttpServletRequest request, PasswordBO passwordBO) {
        log.info("手机用户【" + passwordBO.getMobile() + "】正在根据验证码修改密码" + ",用户所在" + passwordBO.getAppKey() + "平台");
        String regIp = WebUtils.getClientIP(request);
        try {
            String mobile = passwordBO.getMobile();
            String password = passwordBO.getPassword();
            String verifyCoce = passwordBO.getVerifyCode();
            if (StrUtils.isEmpty(mobile) || !MobileUtil.isMobile(mobile) || StrUtils.isEmpty(verifyCoce) || StrUtils.isEmpty(password)) {
                return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
            }
            Map<String, Object> resultMap = userCenterHttps.updatePasswordBySmsCode(passwordBO);
            int code = CodeEnum.FAIL.getCode();
            String msg = CodeEnum.FAIL.getMsg();
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                msg = resultMap.get("msg") == null ? CodeEnum.FAIL.getMsg() : resultMap.get("msg").toString();
                if(backCode == 1){
                    code = 0;
                    msg = CodeEnum.SUCCESS.getMsg();
                }
            }
            return new Result(code, msg);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("根据验证码修改密码修改失败！", e);
            return new Result(CodeEnum.FAIL_100005.getCode(), CodeEnum.FAIL_100005.getMsg());
        }
    }

    /**
     * 获取用户信息
     * @return
     */
    @PostMapping("/get")
    @ApiOperation(value = "获取用户信息", notes = "获取用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long")
    })
    public Result<UserInfoVO> get(Long userId){
        return lotteryServerFeignClient.getUserInfo(userId);
    }

    /**
     * 实名认证
     * @return
     */
    @PostMapping("/realAuth")
    @ApiOperation(value = "实名认证", notes = "实名认证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "realName", value = "真名", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "idCard", value = "身份证", required = true, paramType = "query", dataType = "String")
    })
    public Result realAuth(Long userId, String realName, String idCard){
        return lotteryServerFeignClient.realAuth(userId, realName, idCard);
    }

    @ApiOperation("绑定支付宝")
    @PostMapping("/bindAlipay")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "alipayAccount", value = "支付宝账户", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "openId", value = "支付宝openId", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "authCode", value = "授权令牌", required = true, paramType = "query", dataType = "String")
    })
    public Result bindAlipay(Long userId, String alipayAccount, String openId,String authCode){
        Result result = new Result();
        if(userId == null || StrUtils.isEmpty(alipayAccount) || StrUtils.isEmpty(openId) || StrUtils.isEmpty(authCode)){
            return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
        }
        try {
            //用户中心绑定支付宝
            Result<UserInfoVO> userVOResult = lotteryServerFeignClient.getUserInfo(userId);
            if(!userVOResult.success() || userVOResult.getData() == null){
                return new Result(10020, "用户不存在！");
            }

            Result<List<UserAlipayVO>> aliVOResult = lotteryServerFeignClient.queryUserAlipay(alipayAccount);
            if(!aliVOResult.success()){
                return new Result(aliVOResult.getCode(), aliVOResult.getMsg());
            }
            if(aliVOResult.getData() != null && aliVOResult.getData().size() > 0){
                //账户与绑定的支付宝不一致,提示该支付宝已绑定
                if(!userVOResult.getData().getUserId().equals(aliVOResult.getData().get(0).getUserId()))
                    return new Result(10021, "该支付宝已绑定！");
            }

            /*Map<String, Object> resultMap = userCenterHttps.saveLoginOther(userId, userVOResult.getData().getMobile(), openId, 4);
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
//                String msg = resultMap.get("msg") == null ? "绑定失败" : resultMap.get("msg").toString();
                if(backCode != 1){
                    return new Result(10021, "绑定失败");
                }
            }*/
            //获取支付宝用户信息
            String alipayUser = getAlipayUser(authCode);
            log.info("----------->alipayUser:" + alipayUser);
            int sex = 0 ;
            String city = null;
            if(StrUtils.isNotEmpty(alipayUser)){
                JSONObject jsonObject = JSONObject.parseObject(alipayUser);
                JSONObject json = jsonObject.getJSONObject("alipay_user_info_share_response");
                if("10000".equals(json.getString("code"))){
                    sex = "M".equalsIgnoreCase(json.getString("gender")) ? 2 : 1;
                    city = json.getString("city");
                }
            }
            result =  lotteryServerFeignClient.bindAlipay(userId, alipayAccount, openId, sex, city);
        } catch (Exception e) {
            log.error("userInfo UserInfoCMSVO is error!", e);
            result.setCode(CodeEnum.FAIL_100005.getCode());
            result.setMsg(CodeEnum.FAIL_100005.getMsg());
        }
        return result;
    }

    @ApiOperation("绑定微信")
    @PostMapping("/bindWechat")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "code", value = "code", required = true, paramType = "query", dataType = "String"),
    })
    public Result bindAlipay(Long userId, String code){
        Result result = new Result();
        if(userId == null || StrUtils.isEmpty(code)){
            return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
        }
        try {
            //用户中心绑定微信
            Result<UserInfoVO> userVOResult = lotteryServerFeignClient.getUserInfo(userId);
            if(!userVOResult.success() || userVOResult.getData() == null){
                return new Result(10020, "用户不存在！");
            }
            Map<String,String> accessTokenMap = wechatService.getAccessToken(code);
            String openId = accessTokenMap.get("openId");
            String unionId = accessTokenMap.get("unionId");
            Result<List<UserWechatPO>> wechatPOResult = lotteryServerFeignClient.queryUserWechat(openId);
            if(!wechatPOResult.success()){
                return new Result(wechatPOResult.getCode(), wechatPOResult.getMsg());
            }
            if(wechatPOResult.getData() != null && wechatPOResult.getData().size() > 0){
                //账户与绑定的微信不一致,提示该微信已绑定
                if(!userVOResult.getData().getUserId().equals(wechatPOResult.getData().get(0).getUser_id()))
                    return new Result(10021, "该微信已绑定！");
            }
            /*Map<String, Object> resultMap = userCenterHttps.saveLoginOther(userId, userVOResult.getData().getMobile(), openId, 1);
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                if(backCode != 1){
                    return new Result(10021, "绑定失败");
                }
            }*/
            result =  lotteryServerFeignClient.bindWechat(userId, unionId, openId);
        } catch (Exception e) {
            result.setCode(CodeEnum.FAIL_100005.getCode());
            result.setMsg(CodeEnum.FAIL_100005.getMsg());
        }
        return result;
    }

    private String getAlipayUser(String authCode){
        return alipayService.getUser(alipayService.getAccessToken(authCode));
    }
    @ApiOperation("修改支付密码")
    @PostMapping("/updatePayPassord")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "payPassword", value = "MD5加密", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "verifyCode", value = "验证码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "appKey", value = "appkey", required = true, paramType = "query", dataType = "String")
    })
    public Result updatePayPassord(Long userId, String payPassword, String verifyCode, String appKey, Integer source){
        Result result = new Result();
        if(userId == null || StrUtils.isEmpty(payPassword) || payPassword.length() < 16 || verifyCode == null){
            return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
        }
        try {

            Result<UserInfoVO> voResult = lotteryServerFeignClient.getUserInfo(userId);
            if(!voResult.success()){
                return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
            }
            //胡一刀取消验证码修改密码
            /*UserInfoVO vo = voResult.getData();
            SmsBO smsBO = new SmsBO();
            smsBO.setMobile(vo.getMobile());
            smsBO.setAppKey(appKey);
            smsBO.setAppVersion("1.0.1");
            smsBO.setChannel("未知");
            smsBO.setSource(source);
            smsBO.setVerifyCode(verifyCode);
            Map<String, Object> resultMap = userCenterHttps.verifyCode(smsBO);
            if(resultMap != null){
                int backCode = resultMap.get("code") == null ? 3 : DispatcherUtils.parseInt(resultMap.get("code"));
                String msg = resultMap.get("msg") == null ? CodeEnum.FAIL.getMsg() : resultMap.get("msg").toString();
                if(backCode != 1){
                    return new Result(backCode, msg);
                }
            }*/
            result =  lotteryServerFeignClient.updatePayPassword(userId, payPassword);
        } catch (Exception e) {
            log.error("userInfo UserInfoCMSVO is error!", e);
            result.setCode(CodeEnum.FAIL_100005.getCode());
            result.setMsg(CodeEnum.FAIL_100005.getMsg());
        }
        return result;
    }
    @ApiOperation("修改个人信息")
    @PostMapping("/updateUserInfo")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "headAddress", value = "头像地址", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "nickName", value = "昵称", required = false, paramType = "query", dataType = "String")
    })
    public Result updateUserInfo(Long userId, String headAddress,String nickName){
        Result result = new Result();
        if(userId == null){
            return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
        }
        try {
            result = lotteryServerFeignClient.updateUserInfo(userId, headAddress,nickName);
        } catch (Exception e) {
            result.setCode(CodeEnum.FAIL_100005.getCode());
            result.setMsg(CodeEnum.FAIL_100005.getMsg());
        }
        return result;
    }

    @ApiOperation("钻石兑换")
    @PostMapping("/exchangeDiamonds")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "payAmount", value = "趣豆数量", required = true, paramType = "query", dataType = "BigDecimal")
    })
    public Result updateUserInfo(Long userId, BigDecimal payAmount){
        Result result = new Result();
        if(userId == null){
            return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
        }
        try {
            result = lotteryServerFeignClient.exchangeDiamonds(userId, payAmount);
        } catch (Exception e) {
            result.setCode(CodeEnum.FAIL_100005.getCode());
            result.setMsg(CodeEnum.FAIL_100005.getMsg());
        }
        return result;
    }

    @ApiOperation("任务中心")
    @PostMapping("/taskCenter")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long")
    })
    public Result taskCenter(Long userId){
        Result result = new Result();
        if(userId == null){
            return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
        }
        try {
            result = lotteryServerFeignClient.taskCenter(userId);
        } catch (Exception e) {
            result.setCode(CodeEnum.FAIL_100005.getCode());
            result.setMsg(CodeEnum.FAIL_100005.getMsg());
        }
        return result;
    }

    @ApiOperation("邀请好友数据")
    @PostMapping("/inviteUsersData")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long")
    })
    public Result inviteUsersData(Long userId){
        Result result = new Result();
        if(userId == null){
            return new Result(CodeEnum.FAIL_100002.getCode(), CodeEnum.FAIL_100002.getMsg());
        }
        try {
            result = lotteryServerFeignClient.inviteUsersData(userId);
        } catch (Exception e) {
            result.setCode(CodeEnum.FAIL_100005.getCode());
            result.setMsg(CodeEnum.FAIL_100005.getMsg());
        }
        return result;
    }

}
